package com.fjbdxk.beidou.bd;

import java.util.Date;

/**
 * 设备监控或故障报告系统中，其中设备会发送包含状态信息的数据包到中心服务器。服务器接收到数据包后，可以使用 PacketOption 类来解析数据包的内容
 */
//管理和表示设备数据包中的选项信息，包括设备索引、时间戳、错误类型和错误码。它提供了从字节数组解析数据和将对象状态转换为字节数组的功能。这个设计使得在网络通信中处理设备报文时，能够有效地封装和解析选项信息
public class PacketOption {
    final static int LEN = 5;//PacketOption对象的字节长度，固定为5字节
    final int devIndex;//设备索引号，代表哪个设备的数据包
    final Date dt;//时间戳
    final ET errorType;//错误类型
    final int errorCode;//错误码
/*
构造函数接受设备索引、时间戳、错误类型代码和错误码,将这些参数存储在相应的成员变量中，并将错误类型转换为 ET 枚举值
 */
    PacketOption(int devIndex, Date dt, int errorType, int errorCode) {
        this.devIndex = devIndex;
        this.dt = dt;
        this.errorType = ET.getByCode(errorType);
        this.errorCode = errorCode;
    }
/*
构造函数用于从字节数组中解析 PacketOption 对象
 */
    PacketOption(byte[] pack, Date dtBase) {
        assert pack.length == LEN;
        this.devIndex = Byte.toUnsignedInt(pack[0]);
        int bias = Byte.toUnsignedInt(pack[1]);
        long ldt = dtBase.getTime() + 1000 * bias;
        this.dt = new Date(ldt);
        this.errorType = ET.getByCode(pack[2]);
        this.errorCode = (Byte.toUnsignedInt(pack[3]) << 8) + Byte.toUnsignedInt(pack[4]);
    }
/*
将当前 PacketOption 对象的状态转换为字节数组，以便于传输或存储
 */
    public byte[] getBytes(Date dtBase) {
        byte[] buf = new byte[LEN];
        buf[4] = (byte)(0xFF & errorCode);
        buf[3] = (byte)(0xFF & (errorCode >> 8));
        buf[2] = (byte)(0xFF & errorType.getValue());
        int bias = (int)(this.dt.getTime() - dtBase.getTime()) / 1000;
        buf[1] = (byte)(0xFF & bias);
        buf[0] = (byte)(0xFF & devIndex);

        return buf;
    }

    enum ET{
        ET_0(0, "机组主控报故障"),
        ET_1(1, "CMS系统报警"),
        ET_2(2, "净空监测报警"),
        ET_3(3, "视频监测报警"),
        ET_4(4 ,"其他类型待扩展");
        private final String description;//与每个错误类型相关联的描述字符串
        private final int code;//错误类型的代码

        ET(int code, String description) {
            this.code = code;
            this.description = description;
        }
        //返回错误类型的描述
        public String getDescription() {
            return description;
        }
        //返回错误类型的代码值
        public int getValue() {
            return this.code;
        }
        //根据代码返回相应的 ET 枚举值
        public static ET getByCode(int code) {
            switch (code) {
                case 0:
                    return ET_0;

                case 1:
                    return ET_1;

                case 2:
                    return ET_2;

                case 3:
                    return ET_3;

                default:
                    return ET_4;
            }
        }
    }
}
